module IPFS.Client.Command.Common (
    RepoStat(..),
    Stat(..),
    CIDObject(..)
) where

import Prelude

import Data.Argonaut (class DecodeJson, Json, decodeJson)
import Data.Argonaut.Decode ((.:))
import Data.BigInt (BigInt)
import Data.Either (Either)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Integral (toBigInt)
import Foreign.Object as O

data RepoStat = RepoStat {
  repoSize::Int,
  storageMax::BigInt,
  numObjects::Int,
  repoPath::String,
  version::String
}

derive instance genericRepoStat :: Generic RepoStat _
instance showRepoStat :: Show RepoStat where
  show s = genericShow s


instance repoStatDecodeJson :: DecodeJson RepoStat where
  decodeJson::Json -> Either String RepoStat
  decodeJson json = do
    x <- decodeJson json
    repoSize <- x .: "RepoSize"
    storageMax::Number <- x .: "StorageMax"
    numObjects <- x .: "NumObjects"
    repoPath <- x .: "RepoPath"
    version <- x .: "Version"
    pure $ RepoStat {repoSize:repoSize,storageMax:toBigInt storageMax,numObjects:numObjects,repoPath:repoPath,version:version}

data CIDObject = CIDObject {
  root::String
}

derive instance genericCIDObject :: Generic CIDObject _
instance showCIDObject :: Show CIDObject where
  show s = genericShow s

instance cIDObjectDecodeJson :: DecodeJson CIDObject where
  decodeJson json = do
   dJson::O.Object Json    <- decodeJson json
   root                    <- dJson .: "/"
   pure $ CIDObject {root:root}



data Stat = Stat {
  provideBufLen  ::Int,
  blocksReceived ::BigInt,
  dataReceived   ::BigInt,
  blocksSent     ::BigInt,
  dataSent       ::BigInt,
  dupBlksReceived::BigInt,
  dupDataReceived::BigInt,
  peers          ::Array String,
  wantlist       ::Array CIDObject
}

derive instance genericStat :: Generic Stat _
instance showStat :: Show Stat where
  show s = genericShow s

instance statDecodeJson :: DecodeJson Stat where
  decodeJson json = do
    dJson <- decodeJson json
    provideBufLen  <- dJson .: "ProvideBufLen"
    blocksReceived::Number                  <- dJson .: "BlocksReceived"
    dataReceived::Number                    <- dJson .: "DataReceived"
    blocksSent::Number                      <- dJson .: "BlocksSent"
    dataSent::Number                        <- dJson .: "DataSent"
    dupBlksReceived::Number                 <- dJson .: "DupBlksReceived"
    dupDataReceived::Number                 <- dJson .: "DupDataReceived"
    peers::Array String                     <- dJson .: "Peers"
    wantlist_::Array CIDObject <- dJson .: "Wantlist"
    pure $ Stat {
      provideBufLen:provideBufLen,
      blocksReceived:toBigInt blocksReceived,
      dataReceived:toBigInt dataReceived,
      blocksSent:toBigInt blocksSent,
      dataSent:toBigInt dataSent,
      dupBlksReceived:toBigInt dupBlksReceived,
      dupDataReceived:toBigInt dupDataReceived,
      peers:peers,
      wantlist:wantlist_
    }